#ifndef GAMEENGINE_GRAPHICS_RENDERBUFFER_OBJECT_H
#define GAMEENGINE_GRAPHICS_RENDERBUFFER_OBJECT_H

#include <GameEngine/Graphics/graphics_settings.h>
#include <GameEngine/Graphics/graphic_resource.h>


#ifndef DOXYGEN_IGNORE_ADVANCED

#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//=================================================================================


//! Wrapper for OpenGL renderbuffer objects
/*!
 *  Using OpenGL renderbuffer objects is recommended for advanced users only; for most users, knowing about
 *  the FramebufferObject class will be sufficient.
 *
 *  As its name suggests, renderbuffer objects are objects to which one can render a scene, i.e., they
 *  act as "image" objects. Their role is quite similar to the role of a texture, but they are highly
 *  optimized to act as rendering targets, while textures are most often highly optimized to BE rendered
 *  on the screen.
 *
 *  Renderbuffer objects cannot be filled directly: they are solely useful when they are used together with
 *  a framebuffer object (please see the FramebufferObject class for additional details). This class is
 *  therefore not dedicated to be used directly by client code; it is exposed for programmers that would need
 *  to redefine a framebuffer object class for special purposes (e.g., rendering to multiple targets,
 *  rendering with multisampling activated, rendering depth data, etc).
 *
 @note This class must always be manipulated AFTER a valid OpenGL context has been created. If
       no OpenGL context is available, any call to any function or constructor of this class
	   will result in an application crash.
 */
class _Graphics_decl RenderbufferObject : public GraphicResource {
	GAMEENGINE_DECLARE_RTTI_PARENT(RenderbufferObject,GraphicResource)
	//! The resource manager class is friend of the renderbuffer object class because it must be able to access its ID and context
	friend class ResourceManager<ID,CONTEXTID>;

public:
	//! Typedef used to manage the size of the renderbuffer
	typedef unsigned int RenderbufferSize;

	//! Internal storage format of the renderbuffer
	enum Format {
		//! Data are stored in the RGB format
		RGBFormat = GL_RGB,
		//! Data are stored in the RGBA format
		RGBAFormat = GL_RGBA,
		//! Data are stored as depth data
		DepthFormat = GL_DEPTH_COMPONENT,
		//! Data are stored as stencil data
		StencilFormat = GL_STENCIL_INDEX
	};

public:
	RenderbufferObject();
	RenderbufferObject(const RenderbufferObject& rhs);
	virtual ~RenderbufferObject();
	RenderbufferObject& operator=(const RenderbufferObject& rhs);

	bool initialized() const;

	bool bind_buffer() const;
	bool unbind_buffer() const;

	bool set_storage(RenderbufferSize width, RenderbufferSize height, Format format = DepthFormat);

	ID id() const;

private:
	void clean_id();
	void create_id();

	virtual void destroy_resource() const;
	virtual CONTEXTID context() const;
	virtual ID reference() const;

private:
	ID id_;
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif

#endif
